package net.hn.hnms.biz.equipment.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import net.hn.hnms.biz.equipment.domain.CoalMineSysPointPo;
import net.hn.hnms.biz.equipment.domain.FanHisPo;
import net.hn.hnms.biz.equipment.domain.dto.*;
import net.hn.hnms.biz.equipment.domain.vo.*;
import net.hn.hnms.biz.equipment.mapper.CoalMineSysPointMapper;
import net.hn.hnms.biz.equipment.mapper.FanHisMapper;
import net.hn.hnms.biz.equipment.mapper.FanrealNowMapper;
import net.hn.hnms.biz.equipment.service.CoalMineSysPointService;
import net.hn.hnms.biz.equipment.service.FanrealService;
import net.hn.hnms.biz.equipment.until.OweDateUtils;
import net.hn.hnms.sys.common.core.domain.ResponsePage;
import net.hn.hnms.sys.common.core.utils.DateUtils;
import net.hn.hnms.sys.common.core.utils.StringUtils;
import net.hn.hnms.sys.common.mybatis.core.page.PageQuery;
import net.hn.hnms.sys.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FanrealServiceImpl implements FanrealService {
    @Resource
    private CoalMineSysPointMapper coalMineSysPointMapper;
    @Resource
    private FanrealNowMapper fanrealNowMapper;
    @Resource
    private FanHisMapper fanHisMapper;
    @Resource
    private CoalMineSysPointService coalMineSysPointService;

    /**
     * 分页条件查询实时数据
     *
     * @param pageQuery
     * @param nowDTO
     * @return
     */
    @Override
    public ResponsePage<NowVo> pageNowList(PageQuery pageQuery, NowDto nowDTO) {
        pageQuery.setPageNum(pageQuery.getPageNum() >= 1 ? pageQuery.getPageNum() * pageQuery.getPageSize() : 0);

        // 所属设备
        // 设备位置 去掉“工作面”三个字
        String deviceLocation = nowDTO.getDeviceLocation();
        nowDTO.setDeviceLocation(StringUtils.isNotEmpty(deviceLocation) ? deviceLocation.replace("工作面", "") : null);

        List<SynergiaSysPointDto> list = coalMineSysPointMapper.selectFanPageList(pageQuery.getPageSize(), pageQuery.getPageNum(), nowDTO);
        if (list.isEmpty()) {
            return new ResponsePage<>(new ArrayList(), 0);
        }
        List<NowVo> collect = list.stream().map(t -> {
            NowVo nowVo = new NowVo();
            //测点编码
            nowVo.setPointCode(t.getPointCode());
            //所属设备
            nowVo.setCategory(t.getDeviceName());
            //设备位置
            nowVo.setDeviceLocation(t.getApiPage());
            //测点名称
            nowVo.setPonitName(t.getApiNameCn());
            //数值类型
            nowVo.setValueType(coalMineSysPointService.valueTypeTransitionString(t.getValueType()));
            //检测值
            nowVo.setValue(t.getPointValue());
            //数值单位
            nowVo.setValueUnit(StringUtils.isNotEmpty(t.getSensorUnit()) ? t.getSensorUnit() : "-");
            //检测说明
            nowVo.setValueContent(t.getRemark());
            //数据质量
            nowVo.setDataUality(coalMineSysPointService.dataUalityTransitionString(t.getPointStatus()));
            //数据时间
            nowVo.setDateTime(t.getDataTime());
            return nowVo;
        }).collect(Collectors.toList());
        return new ResponsePage<>(collect, list.get(0).getTotal());

    }

    /**
     * 分页条件查询报警明细
     *
     * @param pageQuery
     * @param abnormalDTO
     * @return
     */
    @Override
    public TableDataInfo<FanHisPo> pageAbnormalInfo(PageQuery pageQuery, AbnormalDto abnormalDTO) {
        pageQuery.setPageNum(pageQuery.getPageNum() >= 1 ? pageQuery.getPageNum() * pageQuery.getPageSize() : 0);

//        Date startTime = new Date();
//        Date endTime = new Date();
//        try {
//            //获取开始时间
//            Date startdate = null;
//            Date endDate = null;
//            if (abnormalDTO.getEndTime() != null && abnormalDTO.getStartTime() != null) {
//                startTime = abnormalDTO.getStartTime();
//                endTime = abnormalDTO.getEndTime();
//                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//                String startTimeString = simpleDateFormat.format(startTime);
//                String endTimeString = simpleDateFormat.format(endTime);
//                startdate = DateUtils.parseDate(startTimeString + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
//                endDate = DateUtils.parseDate(endTimeString + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
//            }
//            Page<SynergiadataAbnormalPo> synergiadataAbnormalPoPage = synergiadataAbnormalMapper.selectPage(pageQuery.build(), new LambdaQueryWrapper<SynergiadataAbnormalPo>()
//                    //统计类型
//                    // TODO
//                    //报警类型
//                    .eq(StringUtils.isNotBlank(abnormalDTO.getExceptionType()), SynergiadataAbnormalPo::getExceptionType, abnormalDTO.getExceptionType())
//                    //异常开始时间
//                    .between(abnormalDTO.getStartTime() != null && abnormalDTO.getEndTime() != null, SynergiadataAbnormalPo::getStartTime, startdate, endDate)
//                    //异常结束时间
//                    .between(abnormalDTO.getStartTime() != null && abnormalDTO.getEndTime() != null, SynergiadataAbnormalPo::getEndTime, startdate, endDate));
//            if (synergiadataAbnormalPoPage.getRecords().isEmpty()) {
//                new TableDataInfo<>();
//            }
//            return TableDataInfo.build(synergiadataAbnormalPoPage);
//        } catch (Exception e) {
//            throw new HuaNengException(Constants.FAIL, "未知错误");
//        }
        return null;
    }


    /**
     * 分页条件查询历史数据
     *
     * @param pageQuery
     * @param hisDTO
     * @return
     */
    @Override
    public ResponsePage<HisVo> pageHistoryInfo(PageQuery pageQuery, HisDto hisDTO) {
        pageQuery.setPageNum(pageQuery.getPageNum() >= 1 ? pageQuery.getPageNum() * pageQuery.getPageSize() : 0);

        // 所属设备
        // 设备位置 去掉“工作面”三个字
        String deviceLocation = hisDTO.getDeviceLocation();
        hisDTO.setDeviceLocation(StringUtils.isNotEmpty(deviceLocation) ? deviceLocation.replace("工作面", "") : null);

        List<SynergiaSysPointDto> list = coalMineSysPointMapper.selectFanHisPageList(pageQuery.getPageSize(), pageQuery.getPageNum(), hisDTO);
        if (list.isEmpty()) {
            return new ResponsePage<>(new ArrayList(), 0);
        }
        List<HisVo> collect = list.stream().map(t -> {
            HisVo hisVo = new HisVo();
            //测点编码
            hisVo.setPointCode(t.getPointCode());
            //所属设备
            hisVo.setCategory(t.getDeviceName());
            //设备位置
            hisVo.setDeviceLocation(t.getApiPage());
            //测点名称
            hisVo.setPonitName(t.getApiNameCn());
            //数值类型
            hisVo.setValueType(coalMineSysPointService.valueTypeTransitionString(t.getValueType()));
            //检测值
            hisVo.setValue(t.getPointValue());
            //数值单位
            hisVo.setValueUnit(StringUtils.isNotEmpty(t.getSensorUnit()) ? t.getSensorUnit() : "-");
            //检测说明
            hisVo.setValueContent(t.getRemark());
            //数据质量
            hisVo.setDataUality(coalMineSysPointService.dataUalityTransitionString(t.getPointStatus()));
            //数据时间
            hisVo.setDateTime(t.getDataTime());
            return hisVo;
        }).collect(Collectors.toList());
        List<HisVo> collectVo = collect.stream().sorted(Comparator.comparing(HisVo::getDateTime).reversed()).collect(Collectors.toList());
        return new ResponsePage<>(collectVo, list.get(0).getTotal());
    }

    /**
     * 获取所属设备下拉列表
     *
     * @return
     */
    @Override
    public List<String> categoryList(String mineCode) {
        LambdaQueryWrapper<CoalMineSysPointPo> coalMineSysPointPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //查询所有协同开采的设备
        coalMineSysPointPoLambdaQueryWrapper.like(CoalMineSysPointPo::getApiCategory, "fan");
        coalMineSysPointPoLambdaQueryWrapper.eq(StringUtils.isNotEmpty(mineCode), CoalMineSysPointPo::getMineCode, mineCode);
        List<CoalMineSysPointPo> coalMineSysPointPoList = coalMineSysPointMapper.selectList(coalMineSysPointPoLambdaQueryWrapper);
        List<String> collect = coalMineSysPointPoList.stream().map(t -> {
            String s = new String();
            s = t.getDeviceName();
            return s;
        }).distinct().collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取设备位置下拉列表
     *
     * @return
     */
    @Override
    public List<String> deviceLocaltionList(String mineCode) {
        LambdaQueryWrapper<CoalMineSysPointPo> coalMineSysPointPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //查询所有协同开采的设备
        coalMineSysPointPoLambdaQueryWrapper.like(CoalMineSysPointPo::getApiCategory, "fan");
        coalMineSysPointPoLambdaQueryWrapper.eq(StringUtils.isNotEmpty(mineCode), CoalMineSysPointPo::getMineCode, mineCode);
        List<CoalMineSysPointPo> coalMineSysPointPoList = coalMineSysPointMapper.selectList(coalMineSysPointPoLambdaQueryWrapper);
        List<String> collect = coalMineSysPointPoList.stream().map(t -> {
            String s = new String();
            s = t.getApiPage();
            return s;
        }).distinct().collect(Collectors.toList());
        return collect;
    }

    /**
     * 条件查询历史数据测点曲线
     *
     * @param pointDto
     * @return
     */
    @Override
    public ChartDateVo pointHistoryCurve(PointDto pointDto) {
        //1天内 日期间隔不做处理
        //1~3天 日期间隔5分钟 取最大值
        //3天~1月  日期间隔1小时 取最大值
        //超过1月  返回前端消息，查询时间范围为一个月

        //查询得数据集合
        List<FanHisPo> coalflowHisPos = null;
        //返回得数据集合Vo
        ChartDateVo chartDateVo = new ChartDateVo();
        List<Date> dateList = new ArrayList<>();
        List<BigDecimal> bigDecimalList = new ArrayList<>();


        if (pointDto.getEndTime().getTime() - pointDto.getStartTime().getTime() <= 3600 * 24 * 1 * 1000L) {
            LambdaQueryWrapper<FanHisPo> queryWrapper = new LambdaQueryWrapper<>();
            //一天内得数据
            queryWrapper.ge(FanHisPo::getDataTime, pointDto.getStartTime());
            //结束时间
            queryWrapper.le(pointDto.getEndTime() != null, FanHisPo::getDataTime, pointDto.getEndTime());
            queryWrapper.eq(FanHisPo::getPointCode, pointDto.getPointCode());

            //煤矿编码
            queryWrapper.eq(StringUtils.isNotEmpty(pointDto.getMineCode()), FanHisPo::getMineCode, pointDto.getMineCode());
            coalflowHisPos = fanHisMapper.selectList(queryWrapper);
        } else if (pointDto.getEndTime().getTime() - pointDto.getStartTime().getTime() <= 3600 * 24 * 3 * 1000L) {
            //三天内得数据
            List<ChartDto> chartDtoList = fanHisMapper.selectOneDayList(pointDto);
            for (ChartDto chartDto : chartDtoList) {
                dateList.add(chartDto.getTime());
                bigDecimalList.add(chartDto.getValue());
            }
            chartDateVo.setDate(dateList);
            chartDateVo.setValue(bigDecimalList);
            return chartDateVo;
        } else if (pointDto.getEndTime().getTime() - pointDto.getStartTime().getTime() <= 3600 * 24 * 31 * 1000L) {
            //1月内得数据
            List<ChartDto> chartDtoList = fanHisMapper.selectOneMonthList(pointDto);
            for (ChartDto chartDto : chartDtoList) {
                dateList.add(chartDto.getTime());
                bigDecimalList.add(chartDto.getValue());
            }
            chartDateVo.setDate(dateList);
            chartDateVo.setValue(bigDecimalList);
            return chartDateVo;
        }

        if (coalflowHisPos.isEmpty()) {

            chartDateVo.setDate(dateList);
            chartDateVo.setValue(bigDecimalList);
            return chartDateVo;
        }
        //list 降序排列
        List<FanHisPo> collect = coalflowHisPos.stream().sorted(Comparator.comparing(FanHisPo::getDataTime).reversed()).collect(Collectors.toList());
        for (FanHisPo coalflowHisPo : collect) {
            dateList.add(coalflowHisPo.getDataTime());
            bigDecimalList.add(new BigDecimal(coalflowHisPo.getPointValue()));
        }
        chartDateVo.setDate(dateList);
        chartDateVo.setValue(bigDecimalList);
        return chartDateVo;
    }

    /**
     * 条件查询历史数据测点列表
     *
     * @param pointDto
     * @return
     */
    @Override
    public List<PointHistoryListVo> pointHistoryList(PointDto pointDto) {
        //1天内 日期间隔不做处理
        //1~3天 日期间隔5分钟 取最大值
        //3天~1月  日期间隔1小时 取最大值
        //超过1月  返回前端消息，查询时间范围为一个月

        //查询得数据集合
        List<FanHisPo> coalflowHisPos = null;
        String stateCode = "1";

        if (pointDto.getEndTime().getTime() - pointDto.getStartTime().getTime() <= 3600 * 24 * 1 * 1000L) {
            LambdaQueryWrapper<FanHisPo> queryWrapper = new LambdaQueryWrapper<>();
            //一天内得数据
            queryWrapper.ge(FanHisPo::getDataTime, pointDto.getStartTime());
            //结束时间
            queryWrapper.le(pointDto.getEndTime() != null, FanHisPo::getDataTime, pointDto.getEndTime());
            queryWrapper.eq(FanHisPo::getPointCode, pointDto.getPointCode());

            //煤矿编码
            queryWrapper.eq(StringUtils.isNotEmpty(pointDto.getMineCode()), FanHisPo::getMineCode, pointDto.getMineCode());
            coalflowHisPos = fanHisMapper.selectList(queryWrapper);
        } else if (pointDto.getEndTime().getTime() - pointDto.getStartTime().getTime() <= 3600 * 24 * 3 * 1000L) {
            //三天内得数据
            List<ChartDto> chartDtoList = fanHisMapper.selectOneDayList(pointDto);
            List<PointHistoryListVo> collect = chartDtoList.stream().map(t -> {
                PointHistoryListVo pointHistoryListVo = new PointHistoryListVo();
                pointHistoryListVo.setDate(t.getTime());
                pointHistoryListVo.setValue(t.getValue());
                pointHistoryListVo.setState(stateCode.equals(t.getState()) ? "正常" : "异常");
                pointHistoryListVo.setStateCode(t.getState());
                return pointHistoryListVo;
            }).collect(Collectors.toList());
            return collect;
        } else if (pointDto.getEndTime().getTime() - pointDto.getStartTime().getTime() <= 3600 * 24 * 31 * 1000L) {
            //1月内得数据
            List<ChartDto> chartDtoList = fanHisMapper.selectOneMonthList(pointDto);
            List<PointHistoryListVo> collect = chartDtoList.stream().map(t -> {
                PointHistoryListVo pointHistoryListVo = new PointHistoryListVo();
                pointHistoryListVo.setDate(t.getTime());
                pointHistoryListVo.setValue(t.getValue());
                pointHistoryListVo.setState(stateCode.equals(t.getState()) ? "正常" : "异常");
                pointHistoryListVo.setStateCode(t.getState());
                return pointHistoryListVo;
            }).collect(Collectors.toList());
            return collect;
        }

        if (coalflowHisPos.isEmpty()) {
            return new ArrayList<>();
        }
        //list 降序排列
        List<FanHisPo> collect = coalflowHisPos.stream().sorted(Comparator.comparing(FanHisPo::getDataTime).reversed()).collect(Collectors.toList());
        List<PointHistoryListVo> collectVo = collect.stream().map(t -> {
            PointHistoryListVo pointHistoryListVo = new PointHistoryListVo();
            pointHistoryListVo.setDate(t.getDataTime());
            pointHistoryListVo.setValue(new BigDecimal(t.getPointValue()));
            pointHistoryListVo.setState(stateCode.equals(t.getPointStatus().toString()) ? "正常" : "异常");
            pointHistoryListVo.setStateCode(t.getPointStatus().toString());
            return pointHistoryListVo;
        }).collect(Collectors.toList());
        return collectVo;
    }

    @Override
    public AnalysisVo getWindPressure() {
        AnalysisVo result = new AnalysisVo("0.00");
        List<ChartAnaliseVo> chartData = new ArrayList<>();
        String endTime = DateUtils.getTime();
        String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addHours(DateUtils.getNowDate(), -1));
        List<String> xData = OweDateUtils.getXData(startTime, endTime, "minutes");
        //  //windPressInValue(入口压力)  windPressOutValue(出口压力)  fan
        List<AnalysisDataDto> chartDtoList = fanHisMapper.getMinutesList("fan", Arrays.asList("windPressInValue", "windPressOutValue"), startTime, endTime);
        xData.remove(xData.size() - 1);
        xData.forEach(x -> {
            AnalysisDataDto in = chartDtoList.stream().filter(item -> item.getDateTime().equals(x) && item.getPointName().equals("windPressInValue")).findFirst().orElse(new AnalysisDataDto("0.0"));
            AnalysisDataDto out = chartDtoList.stream().filter(item -> item.getDateTime().equals(x) && item.getPointName().equals("windPressOutValue")).findFirst().orElse(new AnalysisDataDto("0.0"));
            double v = Double.parseDouble(out.getPointValue()) - Double.parseDouble(in.getPointValue());
            chartData.add(new ChartAnaliseVo(x, v + "", ""));
        });
        result.setChartData(chartData);
        OptionalDouble max = chartData.stream().mapToDouble(u -> Double.parseDouble(u.getY())).max();
        if (max.isPresent()) {
            result.setValue(NumberUtil.roundStr(max.getAsDouble(), 2));
        }
        return result;
    }

    @Override
    public AnalysisVo getAirVolume() {
        AnalysisVo result = new AnalysisVo("0.00");
        List<ChartAnaliseVo> chartData = new ArrayList<>();
        String endTime = DateUtils.getTime();
        String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addHours(DateUtils.getNowDate(), -1));
        OweDateUtils.getXData(startTime, endTime, "minutes");
        List<String> xData = OweDateUtils.getXData(startTime, endTime, "minutes");
        //windAmountValue  fan
        List<AnalysisDataDto> chartDtoList = fanHisMapper.getMinutesList("fan", Collections.singletonList("windAmountValue"), startTime, endTime);
        xData.remove(xData.size() - 1);
        xData.forEach(x -> {
            AnalysisDataDto analysisDataDto = chartDtoList.stream().filter(item -> item.getDateTime().equals(x)).findFirst().orElse(new AnalysisDataDto("0.0"));
            chartData.add(new ChartAnaliseVo(x, analysisDataDto.getPointValue(), ""));
        });
        OptionalDouble max = chartData.stream().mapToDouble(u -> Double.parseDouble(u.getY())).max();
        if (max.isPresent()) {
            result.setValue(NumberUtil.roundStr(max.getAsDouble(), 2));
        }
        result.setChartData(chartData);
        return result;
    }

    @Override
    public List<AnalysisDataDto> getKeyFanIndex() {
        return fanrealNowMapper.getKeyFanIndex();
    }

}
